QTMTB 13 - Access to Decompressed Images during Playback, GWorlds
Title Banner


Technical Q&A's


QTMTB 13 - Access to Decompressed Images during Playback, GWorlds (1-May-95)


Q Is there a mechanism that allows us to access each decompressed image prior to display during playback, so that we could manipulate the image data and then hand it back for display?

A QuickTime 1.6.1 provides a function called SetTrackGWorld. SetTrackGWorld lets you force a track to draw into a particular GWorld. This GWorld may be different from that of the entire movie. After the track is drawn, it will call your transfer procedure to copy the track to the actual movie GWorld. When your transfer procedure is set, the current GWorld is set to the correct destination.

You can also install a transfer procedure and set the GWorld to nil. This results in your transfer procedure being called only as a notification that the track has drawn and that no transfer is taking place.

Inside your transfer procedure you could manipulate the image. Note that calling resource intensive or time consuming routines in your transfer procedure may have an adverse effect on the playback performance of the movie that is playing.

Here's an example of a transfer procedure that will keep a counter of number of times it has been called, and displays this number in the top left corner of the movie:

pascal OSErr myTrackTransferProc(Track t, long refCon)
{

	TransferDataHandle		myTDH = (TransferDataHandle)refCon ;
	GrafPtr			theNewWorld ;
	GrafPtr			movieGWorld ;
	PixMapHandle			offPixMap ;
	Rect				movieBox ;
	static	long			index = 1 ;
	CGrafPtr			savedWorld ;
	GDHandle			savedDevice ;
	Str255				theString ;
	
	

	movieGWorld = (GrafPtr)((**myTDH).movieGWorld) ;
	theNewWorld = (GrafPtr)((**myTDH).trackGWorld) ;
	movieBox    = (**myTDH).movieRect ;
	
	offPixMap = GetGWorldPixMap( (GWorldPtr)theNewWorld ) ;
	(void) LockPixels( offPixMap ) ;
	
	GetGWorld( &savedWorld, &savedDevice );
	SetGWorld( (CGrafPtr)theNewWorld, nil ) ;
	
	MoveTo ( 15, 15 );
	NumToString ( index++, theString );
	DrawString ( theString );
	
	// copy the image from the offscreen port
	// into the movies port
	
	SetGWorld( savedWorld, savedDevice ) ;
	
	CopyBits( 	&theNewWorld->portBits,
				&movieGWorld->portBits,
				&theNewWorld->portRect,
				&movieBox,
				srcCopy,
				nil ) ;

	(void) UnlockPixels( offPixMap ) ;
}


//---------------------------------------------------------------------
// define a structure to hold all the information we need in the transfer
// proc.

typedef struct {
	GWorldPtr	movieGWorld ;
	GWorldPtr	trackGWorld ;
	Rect		movieRect ;
} TransferData, *TransferDataPtr, **TransferDataHandle ;
	
//This has the original movie gWorld, the one we created for the track and a rect 
// describing the movie.  You can set a movie up to use this in the following way:

	TransferDataHandle	myTDH = (TransferDataHandle)NewHandle( sizeof( 							TransferData )) ;
	Track		aTrack = GetFirstTrackOfType( aMovie, VideoMediaType ) ;
	short		trackDepth = GetFirstVideoTrackPixelDepth( aMovie ) ;
	
	if( myTDH == nil || aTrack == nil || trackDepth < 0)
		return ;
		
	GetTrackDimensions( aTrack, &width, &height ) ;
	
	trackDimensions.right = Fix2Long( width );
	trackDimensions.bottom = Fix2Long( height );
	
	// create the movie gWorld
	theErr = NewGWorld( &theNewWorld, trackDepth, &trackDimensions, nil, 						theNewWorldDevice, 0L ) ;
	CheckError( theErr, "\pCall to NewGWorld failed" );

	GetMovieGWorld( aMovie, &movieGWorld, nil ) ;
		
	(**myTDH).movieGWorld = movieGWorld ;
	(**myTDH).trackGWorld = theNewWorld ;
	
	GetMovieBox( aMovie, &movieBox ) ;
	(**myTDH).movieRect = movieBox ;
	
	SetTrackGWorld( aTrack, (CGrafPtr)theNewWorld, nil, myTrackTransferProc,  				(long)myTDH ) ;


Technical Support
Technical Q&As
Previous Question | Contents | Next Question

Navigation graphic, see text links

Main | Page One | What's New | Apple Computer, Inc. | Find It | Contact Us | Help